package com.example.security.config.manager;

import org.springframework.security.access.*;
import org.springframework.security.access.vote.AbstractAccessDecisionManager;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.FilterInvocation;
import org.springframework.stereotype.Component;

import java.util.Collection;
import java.util.List;

/**
 * @author 新梦想.陈超
 * @version 2021.2
 * @Description: {TODO}
 * @date 2022/11/1 下午3:34
 */
public class CustomAccessDecisionManager extends AbstractAccessDecisionManager {       // implements AccessDecisionManager {
    public CustomAccessDecisionManager(List<AccessDecisionVoter<?>> decisionVoters) {
        super(decisionVoters);
    }
    @Override
    public void decide(Authentication authentication, Object object,
                       Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException {

        String requestUrl = ((FilterInvocation) object).getRequestUrl();
        //TODO 1.登录页和登录请求 放行
        if (requestUrl.equals("/login.html") || requestUrl.equals("/login")) {
            return;
        }
        //TODO 2.放行其他无需授权的请求
        if(!authentication.getPrincipal().equals("anonymousUser")
                &&configAttributes.equals(SecurityConfig.createList("ROLE_LOGIN"))){
            return;
        }
        int deny = 0;
        for (AccessDecisionVoter voter : getDecisionVoters()) {
            int result = voter.vote(authentication, object, configAttributes);

            if (logger.isDebugEnabled()) {
                logger.info("Voter: " + voter + ", returned: " + result);
            }
            switch (result) {
                case AccessDecisionVoter.ACCESS_GRANTED:
                    return;

                case AccessDecisionVoter.ACCESS_DENIED:
                    deny++;

                    break;

                default:
                    break;
            }
        }
        if (deny > 0) {
            throw new AccessDeniedException("权限不足");
        }

    }
}